package com.atguigu.spzx.order.service.impl;

import com.atguigu.common.utils.ThreadLocalUtil;
import com.atguigu.spzx.cart.feign.CartServiceFeign;
import com.atguigu.spzx.common.exp.GuiguException;
import com.atguigu.spzx.model.dto.h5.OrderInfoDto;
import com.atguigu.spzx.model.dto.product.SkuSaleDto;
import com.atguigu.spzx.model.entity.h5.CartInfo;
import com.atguigu.spzx.model.entity.order.OrderInfo;
import com.atguigu.spzx.model.entity.order.OrderItem;
import com.atguigu.spzx.model.entity.order.OrderLog;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.entity.user.UserAddress;
import com.atguigu.spzx.model.entity.user.UserInfo;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.h5.TradeVo;
import com.atguigu.spzx.order.mapper.OrderMapper;
import com.atguigu.spzx.order.service.OrderService;
import com.atguigu.spzx.pay.feign.PayServiceFeign;
import com.atguigu.spzx.product.feign.ProductServiceFeign;
import com.atguigu.spzx.user.feign.UserServiceFeign;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {


    @Autowired
    CartServiceFeign cartServiceFeign;

    @Autowired
    UserServiceFeign userServiceFeign;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    PayServiceFeign payServiceFeign;

    @Autowired
    ProductServiceFeign productServiceFeign;
    @Override
    public TradeVo trad() {

        List<CartInfo> cartInfoList = cartServiceFeign.getCartInfoIsCheckedOne();

        List<OrderItem> orderItemList = cartInfoList.stream().map(cartInfo -> {
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(cartInfo.getSkuId());
            orderItem.setSkuName(cartInfo.getSkuName());
            orderItem.setThumbImg(cartInfo.getImgUrl());
            orderItem.setSkuPrice(cartInfo.getCartPrice());
            orderItem.setSkuNum(cartInfo.getSkuNum());


            return orderItem;
        }).collect(Collectors.toList());

        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItemList);
        tradeVo.setTotalAmount(this.calTotalAmount(orderItemList));

        return tradeVo;
    }

    @Transactional
    @Override
    public Long submitOrder(OrderInfoDto orderInfoDto) {

        //1、创建订单
        UserInfo userInfo = ThreadLocalUtil.getUserInfo();
        Long orderInfoId = this.createOrderInfo(userInfo,orderInfoDto);

        //2、添加多个订单明细，每个订单对应一个sku商品，需要进行库存的校验
        this.createOrderItem(orderInfoDto,orderInfoId);

        //3、添加订单日志
        this.createOrderLog(orderInfoId);

        //4、删除购物车中的is_checked=1 的商品
        if (orderInfoDto.getFlag().intValue() ==1){
            cartServiceFeign.deleteCartInfoIsCheckedOne();
        }

        return orderInfoId;
    }

    @Override
    public OrderInfo getByOrderId(Long orderId) {
        OrderInfo orderInfo = orderMapper.getOrderInfo(orderId);
        List<OrderItem> orderInfoList = orderMapper.getOrderItemListById(orderId);
        orderInfo.setOrderItemList(orderInfoList);
        return orderInfo;
    }

    @Override
    public PageInfo findPage(Integer pageNum, Integer pageSize, Integer orderStatus) {

        PageHelper.startPage(pageNum, pageSize);
        Long id = ThreadLocalUtil.getUserInfo().getId();
        List<OrderInfo> list = orderMapper.findList(orderStatus,id);
        for (OrderInfo orderInfo : list) {
            List<OrderItem> orderItemListById = orderMapper.getOrderItemListById(orderInfo.getId());
            orderInfo.setOrderItemList(orderItemListById);
        }
        return new PageInfo<>(list);
    }

    @Override
    public TradeVo buy(Long skuId) {

        ProductSku productId = productServiceFeign.getProductId(skuId);
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productId.getSkuName());
        orderItem.setSkuPrice(productId.getSalePrice());
        orderItem.setThumbImg(productId.getThumbImg());
        orderItem.setSkuNum(1);

        TradeVo tradeVo = new TradeVo();
        tradeVo.setTotalAmount(productId.getSalePrice());
        tradeVo.setOrderItemList(Arrays.asList(orderItem));
        return tradeVo;
    }

    @Override
    public OrderInfo getByOrderNo(String orderNo) {

        OrderInfo orderInfo = orderMapper.getByOrderNo(orderNo);
        orderInfo.setOrderItemList(orderMapper.getOrderItemListById(orderInfo.getId()));
        return orderInfo;
    }

    @Override
    public void afterPaySuccess(String orderNo, Integer payType) {

        Long userid = orderMapper.getByOrderNo(orderNo).getUserId();
       // String username = userServiceFeign.getByUserId(userid).getUsername();
        UserInfo userInfo = userServiceFeign.getByUserId(userid);

        OrderLog orderLog = new OrderLog();
        orderLog.setNote("订单已支付");
        orderLog.setOrderId(orderMapper.getByOrderNo(orderNo).getId());
        orderLog.setOperateUser(userInfo.getUsername());
        orderLog.setProcessStatus(1);
        orderMapper.addOrderLog(orderLog);

        orderMapper.afterPaySuccess(orderNo,payType);
    }

    @Override
    public void cancelOrder(String orderNo,String reason) {
        orderMapper.cancelOrder(orderNo,reason);

        OrderInfo orderInfo = orderMapper.getByOrderNo(orderNo);

        OrderLog orderLog = new OrderLog();
        orderLog.setNote("订单已取消");
        orderLog.setOperateUser(ThreadLocalUtil.getUserInfo().getUsername());
        orderLog.setProcessStatus(-1);
        orderLog.setOrderId(orderInfo.getId());
        orderMapper.addOrderLog(orderLog);

        payServiceFeign.cancelPayment(orderNo);

        List<SkuSaleDto> list = new ArrayList<>();

        List<OrderItem> orderItemList = orderMapper.getOrderItemListById(orderInfo.getId());

        for (OrderItem orderItem : orderItemList) {
            Long skuId = orderItem.getSkuId();
            Integer skuNum = 0-orderItem.getSkuNum().intValue();

            SkuSaleDto skuSaleDto = new SkuSaleDto();
            skuSaleDto.setSkuId(skuId);
            skuSaleDto.setNum(skuNum);
            list.add(skuSaleDto);
        }
        productServiceFeign.updateSkuStockNumAndSaleNum(list);


    }

    private void createOrderLog(Long orderInfoId) {
        OrderLog orderLog = new OrderLog();

        orderLog.setOrderId(orderInfoId);
        String username = ThreadLocalUtil.getUserInfo().getUsername();
        orderLog.setOperateUser(username);//当前用户名
        orderLog.setProcessStatus(0);//订单状态 0：未支付 ， 1：已支付（等待发货）
        orderLog.setNote("提交订单");// 提交订单 、  支付订单 、 取消订单....  订单的不同阶段（状态）的描述

        orderMapper.addOrderLog(orderLog);
    }

    private void createOrderItem(OrderInfoDto orderInfoDto, Long orderInfoId) {
        List<OrderItem> orderItemList = orderInfoDto.getOrderItemList();

        //遍历订单明细集合，每个订单明细都需要进行库存的校验，并且每个订单明细需要为订单id字段赋值
        for (OrderItem orderItem : orderItemList) {
            Long skuId = orderItem.getSkuId();
            Integer skuNum = orderItem.getSkuNum();

            //根据skuid查询当前sku的剩余库存和skuNum比较
            //当前订单服务若想查询某个sku，就去调用商品服务，根据skuId返回sku对象
            ProductSku productSku = productServiceFeign.getProductId(skuId);
            if (productSku.getStockNum().intValue() < skuNum.intValue()) {
                //当前sku商品库存不足
                throw new GuiguException(ResultCodeEnum.STOCK_LESS);
            }

            orderItem.setOrderId(orderInfoId);

            orderMapper.addOrderItem(orderItem);//添加订单明细
        }

    }

    private Long createOrderInfo(UserInfo userInfo, OrderInfoDto orderInfoDto) {
        OrderInfo orderInfo = new OrderInfo();

        orderInfo.setUserId(userInfo.getId());//当前订单所属的用户id
        orderInfo.setNickName(userInfo.getNickName());//当前用户的昵称
        orderInfo.setOrderNo(System.currentTimeMillis() + "");//订单编号（唯一性）

        //优惠券（暂未使用）
        orderInfo.setCouponId(0L);
        orderInfo.setCouponAmount(new BigDecimal(0));

        //计算总金额
        BigDecimal bigDecimal = this.calTotalAmount(orderInfoDto.getOrderItemList());
        orderInfo.setTotalAmount(bigDecimal);//订单总金额
        orderInfo.setOriginalTotalAmount(bigDecimal.add(orderInfoDto.getFeightFee()));//由于没有使用优惠券并且免邮费
        orderInfo.setFeightFee(orderInfoDto.getFeightFee());//免邮费
        orderInfo.setOrderStatus(0);//【0->待付款；1->待发货；2->已发货；3->待用户收货，已完成；-1->已取消】   刚刚创建的订单

        //当前订单需要保存收货地址信息
        Long userAddressId = orderInfoDto.getUserAddressId();//地址id
        UserAddress userAddress = userServiceFeign.findByAddressId(userAddressId);

        orderInfo.setReceiverName(userAddress.getName());//收件人名称
        orderInfo.setReceiverPhone(userAddress.getPhone());//收件人手机号
        orderInfo.setReceiverTagName(userAddress.getTagName());//收货地址别名
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());//省份
        orderInfo.setReceiverCity(userAddress.getCityCode());//城市
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());//区
        orderInfo.setReceiverAddress(userAddress.getFullAddress());//详细地址
        orderInfo.setRemark(orderInfoDto.getRemark());//订单备注

        //调用orderMapper中的添加，将当前orderInfo添加到数据库中，并且返回当前订单的id，返回订单id给前端，并且每个订单明细需要设置orderId字段
        orderMapper.addOrder(orderInfo);

        return orderInfo.getId();
    }

    private BigDecimal calTotalAmount(List<OrderItem> orderItemList) {
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            Integer skuNum = orderItem.getSkuNum();
            BigDecimal skuPrice = orderItem.getSkuPrice();

            BigDecimal sum = skuPrice.multiply(new BigDecimal(skuNum));//乘法

            totalAmount = totalAmount.add(sum);

        }
        return totalAmount;
    }
}
